﻿/*
 * Author: Duncan Jenkins / Martijn Koopman
 * Initial Algorithm using only Hue by: Duncan Jenkins, added code for Saturation and Value by: Martijn Koopman
 * 
 * Description: Color segmentation based on entered Hue, Saturation and Value
 * */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace LibraryCS {
    public class HSVColorSegmentation : VisionAlgorithm {
        private double StartHue = 30, EndHue = 70;
        private double StartSaturation = 0.1, EndSaturation = 1.0;
        private double StartValue = 0.3 , EndValue = 1.0;

        private VImage SourceImage, OutputImage;
        //private Bitmap SourceBitmap, OutputBitmap;

        public HSVColorSegmentation(String name) : base(name) { }

        public VImage SegmentateBitmap ( Bitmap InputBitmap){

            SourceImage = new VImage(InputBitmap);
            OutputImage = new VImage(SourceImage.Width, SourceImage.Height);
            DoSegmentation();

            return OutputImage;
        }

        public VImage SegmentateImage(VImage InputImage)
        {
            SourceImage = InputImage;
            OutputImage = new VImage(SourceImage.Width, SourceImage.Height);
            DoSegmentation();

            return OutputImage;
        }


        public override Bitmap DoAlgorithm(Bitmap inputImage) {
            throw new NotImplementedException();
        }
        public void DoSegmentation(){

            // Create output image

            // Calculate HSV values -> imageHSV[][]
            //if (!SourceImage.hasHSV) {
            SourceImage.calculateHSV();
            //}

            // For each pixel
            for (int i = 0; i < SourceImage.HSV.Length; i++)
            {
                //int x = i % inputImageOps.Width;
                //int y = i / inputImageOps.Width;

                if (SourceImage.HSV[i][0] >= StartHue && SourceImage.HSV[i][0] <= EndHue &&
                    SourceImage.HSV[i][1] >= StartSaturation && SourceImage.HSV[i][1] <= EndSaturation &&
                    SourceImage.HSV[i][2] >= StartValue && SourceImage.HSV[i][2] <= EndValue)
                {
                    // Print in color
                    OutputImage.RedPixels[i] = SourceImage.RedPixels[i];
                    OutputImage.GreenPixels[i] = SourceImage.GreenPixels[i];
                    OutputImage.BluePixels[i] = SourceImage.BluePixels[i];
                } else {
                    /*
                    outputImageOps.RedPixels[i] = 0xFF;
                    outputImageOps.GreenPixels[i] = 0xFF;
                    outputImageOps.BluePixels[i] = 0xFF;
                    */
                }
            }

            
            return;
        }

        #region GUI Functions

        public override SettingsPropertyBox createControls() {
            SettingsPropertyBox Controls = new SettingsPropertyBox();

            // Hue Range ////////////////////
            // Start Hue
            // Label
            Label startHueLb = new Label();
            startHueLb.AutoSize = true;
            startHueLb.Text = "Start Hue";
            startHueLb.Name = "lbStartHue";

            // TextBox
            TextBox startHueTb = new TextBox();
            startHueTb.Name = "tbStartHue";
            startHueTb.AcceptsReturn = false;
            startHueTb.MaxLength = 3;
            startHueTb.Multiline = false;
            startHueTb.Size = new Size(50, 25);
            startHueTb.Text = "" + StartHue ;

            // End Hue
            // Label
            Label endHueLb = new Label();
            endHueLb.AutoSize = true;
            endHueLb.Text = "End Hue";
            endHueLb.Name = "lbEndHue";

            // TextBox
            TextBox endHueTb = new TextBox();
            endHueTb.Name = "tbEndHue";
            endHueTb.AcceptsReturn = false;
            endHueTb.MaxLength = 3;
            endHueTb.Multiline = false;
            endHueTb.Size = new Size(50, 25);
            endHueTb.Text = "" + EndHue;

            // Saturation Range //////////////////// 
            // Start Saturation
            // Label
            Label startSaturationLb = new Label();
            startSaturationLb.AutoSize = true;
            startSaturationLb.Text = "Start Saturation";
            startSaturationLb.Name = "lbStartSaturation";

            // TextBox
            TextBox startSaturationTb = new TextBox();
            startSaturationTb.Name = "tbStartSaturation";
            startSaturationTb.AcceptsReturn = false;
            startSaturationTb.MaxLength = 4;
            startSaturationTb.Multiline = false;
            startSaturationTb.Size = new Size(50, 25);
            startSaturationTb.Text = "" + StartSaturation;

            // End Hue
            // Label
            Label endSaturationLb = new Label();
            endSaturationLb.AutoSize = true;
            endSaturationLb.Text = "End Saturation";
            endSaturationLb.Name = "lbEndSaturation";

            // TextBox
            TextBox endSaturationTb = new TextBox();
            endSaturationTb.Name = "tbEndSaturation";
            endSaturationTb.AcceptsReturn = false;
            endSaturationTb.MaxLength = 4;
            endSaturationTb.Multiline = false;
            endSaturationTb.Size = new Size(50, 25);
            endSaturationTb.Text = "" + EndSaturation;

            // Value Range //////////////////// 
            // Start Value
            // Label
            Label startValueLb = new Label();
            startValueLb.AutoSize = true;
            startValueLb.Text = "Start Value";
            startValueLb.Name = "lbStartValue";

            // TextBox
            TextBox startValueTb = new TextBox();
            startValueTb.Name = "tbStartValue";
            startValueTb.AcceptsReturn = false;
            startValueTb.MaxLength = 4;
            startValueTb.Multiline = false;
            startValueTb.Size = new Size(50, 25);
            startValueTb.Text = "" + StartValue;

            // End Value
            // Label
            Label endValueLb = new Label();
            endValueLb.AutoSize = true;
            endValueLb.Text = "End Value";
            endValueLb.Name = "lbEndValue";

            // TextBox
            TextBox endValueTb = new TextBox();
            endValueTb.Name = "tbEndValue";
            endValueTb.AcceptsReturn = false;
            endValueTb.MaxLength = 4;
            endValueTb.Multiline = false;
            endValueTb.Size = new Size(50, 25);
            endValueTb.Text = "" + EndValue;

            // Add the controls to the list
            Controls.AddLine(startHueLb, startHueTb, endHueLb, endHueTb);
            Controls.AddLine(startSaturationLb, startSaturationTb, endSaturationLb, endSaturationTb);
            Controls.AddLine(startValueLb, startValueTb, endValueLb, endValueTb);

            // Return the list
            return Controls;
        }

        public override void setSettings(List<object> settings) {
            try {
                StartHue = Double.Parse(((string)settings[0]));
                EndHue = Double.Parse(((string)settings[1]));
                StartSaturation = Double.Parse(((string)settings[2]));
                EndSaturation = Double.Parse(((string)settings[3]));
                StartValue = Double.Parse(((string)settings[4]));
                EndValue = Double.Parse(((string)settings[5]));

                Debug.WriteLine("Settings entered:");
                Debug.WriteLine("Hue range " + StartHue + " - " + EndHue);
                Debug.WriteLine("Saturation range " + StartSaturation + " - " + EndSaturation);
                Debug.WriteLine("Value range " + StartValue + " - " + EndValue);
            } catch (FormatException) {
                MessageBox.Show("Wrong Format has been entered.\nPlease enter integers\nNew Settings have been discarded for HSVColorSegmentation", "Format Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }

        #endregion

    }
}
